import React, { useState } from 'react';
import {
    Box, Typography, Paper, Button, TextField, Divider,
    Chip, Stack, CircularProgress, Alert
} from '@mui/material';
import { useAppContext } from '../contexts/AppContext';
import { useContract } from '../hooks/useContract';

const MethodCaller: React.FC = () => {
    const { state } = useAppContext();
    const { callMethod } = useContract();
    const [args, setArgs] = useState<Record<string, any>>({});
    const [isLoading, setIsLoading] = useState(false);

    const handleArgChange = (inputName: string, value: string) => {
        setArgs(prev => ({ ...prev, [inputName]: value }));
    };

    const handleCallMethod = async () => {
        if (!state.currentMethod) return;

        setIsLoading(true);
        const argsArray = state.currentMethod.inputs.map(input => args[input.name] || '');
        const isReadOnly = state.currentMethod.stateMutability === 'view' ||
            state.currentMethod.stateMutability === 'pure';

        await callMethod(state.currentMethod, argsArray, isReadOnly);
        setIsLoading(false);
    };

    if (!state.currentMethod) {
        return (
            <Paper elevation={3} sx={{ p: 3 }}>
                <Typography variant="h6" gutterBottom>
                    Method Interaction
                </Typography>
                <Divider sx={{ mb: 2 }} />
                <Typography>Select a method to interact with</Typography>
            </Paper>
        );
    }

    return (
        <Paper elevation={3} sx={{ p: 3 }}>
            <Typography variant="h6" gutterBottom>
                {state.currentMethod.name}
            </Typography>
            <Divider sx={{ mb: 2 }} />

            <Stack direction="row" spacing={1} sx={{ mb: 2 }}>
                <Chip
                    label={state.currentMethod.stateMutability}
                    color={
                        state.currentMethod.stateMutability === 'view' ||
                        state.currentMethod.stateMutability === 'pure'
                            ? 'success'
                            : 'warning'
                    }
                />
                {state.currentMethod.outputs.length > 0 && (
                    <Chip
                        label={`returns ${state.currentMethod.outputs.map(o => o.type).join(', ')}`}
                        color="info"
                    />
                )}
            </Stack>

            {state.currentMethod.inputs.length > 0 ? (
                <Box sx={{ mb: 3 }}>
                    <Typography variant="subtitle1" gutterBottom>
                        Parameters:
                    </Typography>
                    {state.currentMethod.inputs.map((input, index) => (
                        <TextField
                            key={index}
                            label={`${input.name} (${input.type})`}
                            variant="outlined"
                            fullWidth
                            value={args[input.name] || ''}
                            onChange={(e) => handleArgChange(input.name, e.target.value)}
                            sx={{ mb: 2 }}
                        />
                    ))}
                </Box>
            ) : (
                <Typography sx={{ mb: 3 }}>This method has no parameters.</Typography>
            )}

            <Button
                variant="contained"
                color="primary"
                onClick={handleCallMethod}
                disabled={isLoading}
                startIcon={isLoading ? <CircularProgress size={20} /> : null}
            >
                {isLoading ? 'Processing...' : 'Call Method'}
            </Button>

            {(state.result || state.error) && (
                <Box sx={{ mt: 3 }}>
                    <Typography variant="subtitle1" gutterBottom>
                        Result:
                    </Typography>
                    {state.error ? (
                        <Alert severity="error">{state.error}</Alert>
                    ) : (
                        <Paper variant="outlined" sx={{ p: 2 }}>
              <pre style={{ margin: 0, overflowX: 'auto' }}>
                {JSON.stringify(state.result, null, 2)}
              </pre>
                        </Paper>
                    )}
                </Box>
            )}
        </Paper>
    );
};

export default MethodCaller;